/**
 * Created by Administrator on 2017/1/16.
 */
var config = require('./config');
var MJPlayer = require('../MJ/player').MJPlayer;
var MJ = require('../MJ/MJ');
var Const = require('./const');

exports.HSMJPlayer = MJPlayer.extend({

    init: function (uid, msg) {
        this._super(uid, msg);

        this._stat.zmCount = 0;             // 自摸次数
        this._stat.dpCount = 0;             // 点炮次数
        this._stat.dhCount = 0;             // 点胡次数

        this._stat.hCount = 0;

        this._stat.anGangCount = 0;        // 暗杠次数
        this._stat.mingGangCount = 0;      // 明杠次数
        this._stat.pengCount = 0;         //碰的次数
        this._stat.chiCount = 0;            //吃牌次数
        this._hundiao=false;

        // this._stat.remainScore = 1000;     // 剩余积分
        //吃碰明杠次数
        this._chiCount = 0;
        this._pengCount = 0;
        this._gangCount = 0;
        this._angangCount = 0;
        this._mingGangCount = 0;
        this._FS = {};
        this._words = 0;
        this._score = 0;
        this._lpCards = 0;               //亮牌次数
        this._MQ = false;
        this._HuStyle = 0;
        this._baseScore = 0;
        this._isdp = false;
        this._isZM = false;
    },
    reset: function () {
        this._FS = {};
        this._words = 0;
        this._score = 0;
        this._lpCards = 0;               //亮牌次数
        this._MQ = false;
        this._chiCount = 0;
        this._pengCount = 0;
        this._gangCount = 0;
        this._angangCount = 0;
        this._mingGangCount = 0;
        this._baseScore = 0;
        this._isdp = false;
        this._isZM = false;

        this._hundiao=false;

    },
    setFS: function (info) {
        var room = this.getRoom();
        if (info == 'YH' && this._FS['YH']) {
            return;
        }
        if (this._FS[info]) {
            if (info == 'LLZ') {
                return;
            }
            if(info == 'SJH' || info == 'TJH'){
                return;
            }
            this._FS[info] += Const.RaiseFSInfo[info];
            //room._scoreFSLine += Const.RaiseFSInfo[info];
            return;
        } else if (info == 'SJH') {
            delete this._FS['TJH'];
            this._FS[info] = Const.RaiseFSInfo[info];
        }
        else {
            this._FS[info] = Const.RaiseFSInfo[info];
        }

        //room._scoreFSLine += Const.RaiseFSInfo[info];
    },
    delFS: function (info) {
        if (this._FS[info]) {
            delete this._FS[info];
        }
    },
    settlementGangScore: function () {
        this._super();
    },
    _getSpecGang: function (type) {
        var result = null;
        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];
            if (gangInfo.type == type) {
                result = gangInfo;
                break;
            }
        }
        return result;
    },
    //
    checkTing: function () {
        return [];
    },
    getChiCount: function () {
        return this._chiCount;
    },
    getPengCount: function () {
        return this._pengCount;
    },
    getDgangCount: function () {
        return this._gangCount;
    },

    //检测点杠牌
    checkGangWithCard: function (card) {
        var room = this.getRoom();
        var lz = room.getLZCard();
        if (room.getHZFCLZG()) {
            if (card == lz) {
                return false;
            } else if (card == MJ.ZI.HZ || card == MJ.ZI.FC) {
                return false;
            }
        } else {
            if (card == lz) {
                return false;
            } else if (card == MJ.ZI.HZ) {
                return false;
            }
        }
        return (this._handCards.getCardNum(card) == 3);
    },
    gangCard: function (gangTask) {
        var selectGang = gangTask.selectGang || 0;
        if (selectGang > gangTask.gangArray.length) {
            selectGang = 0;
        }

        var selectGangTask = gangTask.gangArray[selectGang];


        return this._super(selectGangTask);
    },

    //检测碰牌
    checkPengWithCard: function (card) {
        var room = this.getRoom();
        var LZ = room.getLZCard();
        if (card == LZ || card == MJ.ZI.HZ) {
            return false;
        }
        if (room.getHZFCLZG()) {
            if (card == MJ.ZI.FC) {
                return false;
            }
        }

        return this._handCards.getCardNum(card) >= 2;

    },
    pengCard: function (task) {
        var card = task.card;
        if (!this._handCards.peng(card)) {
            logger.error("room=%d index=%d pengCard task=%d failed", this.getRoom().rid(), this.getIndex(), task);
            return false;
        }

        this._pengCards.push(card);
        this._pengCardsFrom[card] = task.from;
        this._stat.pengCount += 1;
        logger.debug("room=%d index=%d pengCard task=%j cards=%j", this.getRoom().rid(), this.getIndex(), task, this._handCards.getCards());
        return true;
    },
    //检测吃牌
    checkChiCondition: function (card) {

        var room = this.getRoom();
        var color = MJ.getColor(card);
        if (color == MJ.Color.ZI) {
            return false;
        }
        if (card == room.getLZCard()) {
            return false;
        }
        return true;
    },
    chiCard: function (chiTask) {
        if (this._super(chiTask)) {
            this._chiCount += 1;
            return true;
        }
        return false;
    },
    checkHu: function () {


        var subConfig = this.getRoom().getSubConfig();
        var cards = this._handCards.getCards();

        return this.checkHuLogic(cards, this.getLastCard());
    },
    checkHuWithCard: function (card) {
        //不能胡红中发财赖子
        var room = this.getRoom();
        if (room.getHZFCLZG()) {
            if (card == MJ.ZI.HZ || card == MJ.ZI.FC || card == room.getLZCard()) {
                return Const.Pattern.NONE;
            }
        } else {
            if (card == MJ.ZI.HZ || card == room.getLZCard()) {
                return Const.Pattern.NONE;
            }
        }

        var cards = clone(this._handCards.getCards());
        ExObject.addNumber(cards, card, 1);

        return this.checkHuLogic(cards, card);
    },
    //判断清一色
    checkQYS: function (pattern,huCard) {

        var room = this.getRoom();
        if (pattern == Const.Pattern.NONE) {
            return pattern;
        }
        var colors = {};

        var handleCards = clone(this._handCards.getCards())
        handleCards[room.getLZCard()] = 0;
        ExObject.eachKeyNum(handleCards, function (card, num) {
            if (num > 0) {
                colors[MJ.getColor(card)] = 1;
            }
        });
        colors[MJ.getColor(huCard)] = 1
        this._pengCards.forEach(function (card) {
            colors[MJ.getColor(card)] = 1;
        });

        this._chiCards.forEach(function (chiInfo) {
            colors[MJ.getColor(chiInfo.card)] = 1;
        });

        this._gangCards.forEach(function (gangInfo) {

            colors[MJ.getColor(gangInfo.card)] = 1;
        });

        var colorNum = Object.keys(colors).length;

        if (colorNum == 1) {
            switch (pattern) {
                case Const.Pattern.NORMAL:
                    pattern = Const.Pattern.QIS;
                    break;
                case Const.Pattern.PAIR:
                    pattern = Const.Pattern.QISPAIR;
                    break;
                case Const.Pattern.PAIR7:
                    pattern = Const.Pattern.QISPAIR7
                    break;
                case Const.Pattern.JJH:
                    pattern = Const.Pattern.QISJJH;
                    break;
                // case Const.Pattern.HHPAIR7:
                //     pattern = Const.Pattern.QYSHHPAIR7;
            }
            this._HuStyle = pattern;
            return pattern;
        }

        if (!pattern) {
            return Const.Pattern.NONE;
        }

        this._HuStyle = pattern;
        return pattern;
    },
    checkJJH: function (cards, lzCard) {
        var room = this.getRoom();
        var flag = true;
        if (this._chiCount) {
            return false;
        }
        //cards[lzCard] = 0;
        ExObject.each(cards, function (k, v) {
            if (k != room.getLZCard()) {
                var temp = MJ.getPoint(k);
                if (temp != 2 && temp != 5 && temp != 8) {
                    flag = false;
                }
            }
        });
        this._pengCards.forEach(function (card) {
            if (MJ.getPoint(card) != 2 && MJ.getPoint(card) != 5 && MJ.getPoint(card) != 8) {
                flag = false;
            }

        });
        this._gangCards.forEach(function (gangInfo) {
            if (MJ.getPoint(gangInfo.card) != 2 && MJ.getPoint(gangInfo.card) != 5 && MJ.getPoint(gangInfo.card) != 8) {
                flag = false;
            }
        });


        return flag;
    },
    signQYS:function (cards,huCard) {
        var room = this.getRoom();
        var handleCards = clone(cards)
        var colors = {};
        handleCards[room.getLZCard()] = 0;
        ExObject.eachKeyNum(handleCards, function (card, num) {
            if (num > 0) {
                colors[MJ.getColor(card)] = 1;
            }
        });
        colors[MJ.getColor(huCard)] = 1
        this._pengCards.forEach(function (card) {
            colors[MJ.getColor(card)] = 1;
        });

        this._chiCards.forEach(function (chiInfo) {
            colors[MJ.getColor(chiInfo.card)] = 1;
        });

        this._gangCards.forEach(function (gangInfo) {

            colors[MJ.getColor(gangInfo.card)] = 1;
        });
        var existColorZI = colors.hasOwnProperty(MJ.Color.ZI);
        if(existColorZI){
           return false;
        }
        var colorNum = Object.keys(colors).length;

        if (colorNum == 1) {
            return true;
        }
        return false;
    },
    checkHunDiao:function(cards){
        var room = this.getRoom();
        var newCards = clone(cards);
        var baocard = room.getLZCardNum(this);
        if(baocard < 1){
            return false;
        }
        newCards[room.getLZCard()] -= 1;
        baocard -= 1;

        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var num1 = 0;
        var num = 0;

        var curBaocard = baocard;
        this._isBaoHu = true;
        ExObject.eachKeyNum(newCards, function (c, n) {
            if (c != room.getLZCard()) {
                if (n == 2) {
                    num2++;
                } else if (n == 3) {
                    num3++;
                } else if (n == 4) {
                    num4++;
                }else{
                    num1++;
                }
            }
            num += n;
        });
        //七对
        if(num2 + num4 * 2 == 6 - curBaocard){
            return true;
        }
        num4 = 0;
        num3 = 0;
        num2 = 0;
        num1 = 0;
        num = 0;
        //碰碰胡
        ExObject.eachKeyNum(newCards, function (c, n) {
            if (c != room.getLZCard()) {
                if (n == 2) {
                    if(curBaocard){
                        curBaocard--;
                        num3++;
                    }else {
                        num2++;
                    }
                } else if (n == 3) {
                    num3++;
                } else if (n == 4) {
                    num4++;
                }else{
                    if(curBaocard >= 2){
                        curBaocard -= 2;
                        num3++;
                    }else {
                        num1++;
                    }
                }
            }
            num += n;
        });
        if(num3 * 3 == num){
            return true;
        }
        //平胡
        var colors = room.getSubConfig().colors;
        var hu3x2 = false;
        curBaocard = baocard;
        var pattern = MJ.Pattern.NORMAL;
        //遍历每个花色
        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(newCards, color);
            //如果颜色是宝牌颜色，去除宝牌再检测
            if (color == MJ.getColor(room.getLZCard())) {
                colorCards[room.getLZCard()] = 0;
            }
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum == 0) {
                continue;
            }
            var context = {
                result: false,
                hu3x2:true,
                curbaocard:curBaocard
            };

            if (MJ.isBasicColor(color)) {
                this.checkColor3XCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards, context);
            }
            if(!context.result){
                return false;
            }
            curBaocard = context.curbaocard;
        }
        return true;
    },
    //混调用3X
    checkColor3XCards: function(minCard, maxCard, cards, context){
        var colorCardsNum = MJ.sumCardsNum(cards);
        for(var bn = 0; bn <= context.curbaocard; bn++){
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if(curmodNum == 0){
                this.checkBaoHu3X(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            }
        }
    },
    checkHuNLogic: function (cards, huCard) {
        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var num = 0;

        ExObject.each(cards, function (c, n) {
            if (n == 2) {
                num2++;
            } else if (n == 3) {
                num3++;
            } else if (n == 4) {
                num4++;
            }
            num += n;
        });

        if (num == 2 && this._chiCards.length <= 0) { // 碰碰胡
            return (num2 == 1) ? Const.Pattern.PAIR : MJ.Pattern.NONE;
        }
        // var newCards = clone(cards);
        // if (this.check13BuDa(newCards, this._isBaoHu)) {//十三不搭
        //     return Const.Pattern.ONE13;
        // }
        var flag = true;
        if (this._chiCount) {
            flag = false;
        }
        //cards[lzCard] = 0;
        ExObject.each(cards, function (k, v) {

            var temp = MJ.getPoint(k);
            if (temp != 2 && temp != 5 && temp != 8) {
                flag = false;
            }

        });
        this._pengCards.forEach(function (card) {
            if (MJ.getPoint(card) != 2 && MJ.getPoint(card) != 5 && MJ.getPoint(card) != 8) {
                flag = false;
            }

        });
        this._gangCards.forEach(function (gangInfo) {
            if (MJ.getPoint(gangInfo.card) != 2 && MJ.getPoint(gangInfo.card) != 5 && MJ.getPoint(gangInfo.card) != 8) {
                flag = false;
            }
        });


        if (flag) {
            return Const.Pattern.JJH;
        }


        if ((num2 + num4 * 2) == 7) { // 七对
            return Const.Pattern.PAIR7;
        }
        if (num2 == 1 && ((num3 * 3 + 2) == num) && this._chiCards.length <= 0) { // 大对子
            return Const.Pattern.PAIR;
        }
        var room = this.getRoom();
        var colors = room.getSubConfig().colors;

        var pattern = MJ.Pattern.NORMAL;
        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(cards, color);

            if (MJ.isBasicColor(color)) {
                if (!MJ.checkHuColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards)) {
                    pattern = MJ.Pattern.NONE; break;
                }
            } else {
                var context = {
                    result: false,
                    hu3x2: false,
                    curbaocard: 0
                };
                this.checkBaoPairColorCards(colorCards, context)
                if (!context.result) {
                    pattern = MJ.Pattern.NONE; break;
                }
            }
        }
        return pattern;
    },
    checkHuLogic: function (cards, huCard) {
        var room = this.getRoom();
        var isSign = this.signQYS(this._handCards.getCards(),huCard)

        //手中有红中发财不能胡
        if (room.getHZFCLZG()) {
            if (MJ.existCard(cards, MJ.ZI.HZ) || MJ.existCard(cards, MJ.ZI.FC)) {
                return MJ.Pattern.NONE;
            }
        } else {
            if (MJ.existCard(cards, MJ.ZI.HZ)) {
                return MJ.Pattern.NONE;
            }
        }
        //是否是硬胡
        this.delFS('YH');
    
        if (this.checkHuNLogic(cards, huCard) != Const.Pattern.NONE) {
            this.setFS('YH');
           
        }
        var baocard = room.getLZCardNum(this);
        var pattern = MJ.Pattern.NONE;
        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var num1 = 0;
        var num = 0;
        var curBaocard = baocard;
        ExObject.eachKeyNum(cards, function (c, n) {
            if (c != room.getLZCard()) {
                if (n == 2) {
                    num2++;
                } else if (n == 3) {
                    num3++;
                } else if (n == 4) {
                    num4++;
                } else {
                    num1++;
                }
            }
            num += n;
        });

        //将将胡 和将碰碰胡
        if (this.checkJJH(cards, room.getLZCard())) {
            var newCards = clone(cards);
            if (this.checkBaoHuBigPair(newCards, baocard) && this._chiCards.length <= 0) {
                return Const.Pattern.JPPH;
            }
            return this.checkQYS(Const.Pattern.JJH,huCard);
        }
        var newCards = clone(cards);
        var resultP = this.checkBaoHuPair7(newCards, baocard);
        if (resultP == Const.Pattern.HHPAIR7) {
            // 七对
            this._HuStyle = Const.Pattern.HHPAIR7;
            return Const.Pattern.HHPAIR7;
        } else if (resultP == true) {

            return this.checkQYS(Const.Pattern.PAIR7,huCard);
        }
        newCards = clone(cards);
        if (this.checkBaoHuBigPair(newCards, baocard) && this._chiCards.length <= 0) { //// 碰碰胡

            return this.checkQYS(Const.Pattern.PAIR,huCard);
        }


        var colors = room.getSubConfig().colors;


        var hu3x2 = false;
        curBaocard = baocard;
        pattern = MJ.Pattern.NORMAL;

        //遍历每个花色

        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(cards, color);
            //如果颜色是宝牌颜色，去除宝牌再检测
            if (color == MJ.getColor(room.getLZCard())) {
                colorCards[room.getLZCard()] = 0;
            }
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum == 0) {
                continue;
            }
            var context = {
                result: false,
                hu3x2: hu3x2,
                curbaocard: curBaocard
            };
            if (MJ.isBasicColor(color)) {
                this.checkBaoColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards, context);
            } else {
                this.checkBaoPairColorCards(colorCards, context);
            }
            if (!context.result) {
                pattern = MJ.Pattern.NONE; break;
                
            }
            hu3x2 = context.hu3x2;
            curBaocard = context.curbaocard;
        }
        pattern = this.checkQYS(pattern,huCard)
        if(pattern == MJ.Pattern.NORMAL && room.getCurPlay() != this.getIndex()&& room.getLZCardNum(this) >= 2){
            return MJ.Pattern.NONE;
        }
        if(pattern == MJ.Pattern.NORMAL && this._hundiao  && room.getCurPlay() != this.getIndex()){
            return MJ.Pattern.NONE;
        }
        return pattern;

    },
    checkBaoHuBigPair: function (cards, baocard) {
        var num = 0;
        var num1 = 0;
        var num2 = 0;
        var num3 = 0;
        var num4 = 0;
        var card = baocard;
        var room = this.getRoom();
        ExObject.eachKeyNum(cards, function (c, n) {
            if (c != room.getLZCard()) {
                if (n == 2) {
                    if (card) {
                        card--;
                    } else {
                        num2++;
                    }
                } else if (n == 4) {
                    num4++;
                } else if (n == 3) {
                } else if (n == 1) {
                    if (card) {
                        card--;
                        num2++;
                    } else {
                        num1++;
                    }
                }
            }
            num++;
        });
        if (num2 == 2 && num1 == 0 && card > 0 && num4 == 0) {
            return true
        } else if (num1 == 1 && num2 == 0 && card > 0 && num4 == 0) {
            return true
        } else if (num1 == 0 && num2 == 0 && num4 == 0) {
            return true;
        } else if (num2 == 1 && num1 == 0 && num4 == 0) {
            return true;
        }
        return false
    },
    checkBaoHuPair7: function (cards, baocard) {
        var num = 0;
        var num3 = 0;
        var num4 = 0;
        var numPair = 0;
        var room = this.getRoom();
        ExObject.each(cards, function (c, n) {
            if (c != room.getLZCard()) {
                if (n == 2) {
                    numPair += 1;
                    num += 1;
                    cards[c] = 0;
                } else if (n == 4) {
                    num += 2;
                    num4 += 1;
                    cards[c] = 0;
                } else if (n == 3) {
                    num += 1;
                    num3 += 1
                    cards[c] -= 2;
                }
            }
        });
        if (num == 6 && baocard == 2) {
            this.delFS('YH');
            return Const.Pattern.HHPAIR7;
        }

        if (num == (7 - baocard)) {
            if (numPair == 6 && baocard >= 2) {

                return Const.Pattern.HHPAIR7;
            }
            else if (baocard == 1 && num3 > 1) {
                return Const.Pattern.HHPAIR7;
            } else if (num4 > 0) {
                return Const.Pattern.HHPAIR7;
            }
            return true;
        } else {
            return false;
        }
    },
    checkBaoColorCards: function (minCard, maxCard, cards, context) {
        var colorCardsNum = MJ.sumCardsNum(cards);
        for (var bn = 0; bn <= context.curbaocard; bn++) {
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if (curmodNum == 0) {
                this.checkBaoHu3X(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            } else if (curmodNum == 2 && !context.hu3x2) {
                this.checkBaoHu3X2(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    context.hu3x2 = true;
                    break;
                }
            }
        }
    },
    checkBaoHu3X2: function (minCard, maxCard, cards, context, baocard) {
        var room = this.getRoom();
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (num >= 2) {
                var newCards = clone(cards);
                newCards[i] = num - 2;
                var newBaocard = baocard;
                this.checkBaoHu3X(minCard, maxCard, newCards, context, newBaocard);
                if (context.result) {
                    context.result = true;
                    break;
                }
            } else if (num == 1 && baocard) {
                var newCards = clone(cards);
                newCards[i] = 0;
                var newBaocard = baocard;
                newBaocard--;
                this.checkBaoHu3X(minCard, maxCard, newCards, context, newBaocard);
                if (context.result) {
                    context.result = true;
                    break;
                }
            }
        }
    },
    checkBaoHuColorCards: function (minCard, maxCard, colorCards, baocard) {
        var colorCardsNum = MJ.sumCardsNum(colorCards);
        var room = this.getRoom();
        if (colorCardsNum == 0) {
            return true;
        }

        var context = { result: false };
        var modNum = (colorCardsNum + baocard) % 3;
        if (modNum == 0) {
            this.checkBaoHu3X(minCard, maxCard, colorCards, context, baocard)
        } else if (modNum == 2) {
            if (baocard) {
                this.checkBaoHu3X(minCard, maxCard, colorCards, context, baocard)
            }
            this.checkBaoHu3X2(minCard, maxCard, colorCards, context, baocard);
            if (!context.result) {

            }
        }
        return context.result;

    },

    checkBaoPairColorCards: function (cards, context) {
        var colorCardsNum = MJ.sumCardsNum(cards);
        for (var bn = 0; context.curbaocard >= bn; bn++) {
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if (curmodNum == 0) {
                context.result = this.checkBaoPairHuColorCards(cards, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            } else if (curmodNum == 2 && !context.hu3x2) {
                for (var i = 1; i <= 7; ++i) {
                    var num = cards[i];
                    if (num >= 2) {
                        var newCards = clone(cards);
                        newCards[i] = num - 2;
                        context.result = this.checkBaoPairHuColorCards(newCards, curbn);
                        if (context.result) {
                            break;
                        }
                    } else if (num == 1 && context.curbaocard) {
                        var newCards = clone(cards);
                        newCards[i] = 0;
                        curbn--;
                        context.result = this.checkBaoPairHuColorCards(newCards, curbn);
                        if (context.result) {
                            break;
                        }
                    }
                }
                if (context.result) {
                    context.curbaocard -= curbn;
                    context.hu3x2 = true;
                    break;
                }
            }
            if (context.result) {
                break;
            }
        }
    },
    checkBaoHu3X: function (minCard, maxCard, cards, context, baocard) {
        var room = this.getRoom();
        var colorCardsNum = MJ.sumCardsNum(cards);
        if (colorCardsNum < 1) {
            context.result = true;
            return;
        }
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (!num) {
                continue;
            }
            var num2 = cards[i + 1];
            var num3 = cards[i + 2];
            if (num == 3) {
                if (num2 > 0 && num3 > 0) {
                    var iTmp = 0;
                    if (num2 < 3) {
                        iTmp += 3 - num2;
                    }
                    if (num3 < 3) {
                        iTmp += 3 - num3;
                    }
                    if (iTmp <= baocard) {
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[i] = 0;
                        if (num2 >= 3) {
                            newCards[i + 1] = num2 - 3;
                        } else {
                            newbaocard -= 3 - newCards[i + 1];
                            newCards[i + 1] = 0;
                        }
                        if (num3 >= 3) {
                            newCards[i + 2] = num3 - 3;
                        } else {
                            newbaocard -= 3 - newCards[i + 2];
                            newCards[i + 2] = 0;
                        }
                        this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                    }
                }
                cards[i] = 0;
                this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
            } else if (num == 2) {
                if (num2 > 0 && num3 > 0) {
                    var iTmp = 0;
                    if (num2 < 2) {
                        iTmp += 2 - num2;
                    }
                    if (num3 < 2) {
                        iTmp += 2 - num3;
                    }
                    if (iTmp <= baocard) {
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[i] = 0;
                        if (num2 >= 2) {
                            newCards[i + 1] = num2 - 2;
                        } else {
                            newbaocard -= 2 - newCards[i + 1];
                            newCards[i + 1] = 0;
                        }
                        if (num3 >= 2) {
                            newCards[i + 2] = num3 - 2;
                        } else {
                            newbaocard -= 2 - newCards[i + 2];
                            newCards[i + 2] = 0;
                        }
                        this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                    }
                }
                if (baocard) {
                    cards[i] = 0;
                    baocard--;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
                if (((num2 || num3) && baocard) || (num2 && num3)) {
                    var newCards = clone(cards);
                    var newbaocard = baocard;
                    newCards[i] = num - 1;
                    if (num2) {
                        newCards[i + 1] = num2 - 1;
                    } else {
                        newbaocard--;
                    }
                    if (num3) {
                        newCards[i + 2] = num3 - 1;
                    }
                    else {
                        newbaocard--;
                    }
                    this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                }
                if (num == 1 && baocard >= 2) {
                    cards[i] = 0;
                    baocard -= 2;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
            } else {
                if (((num2 || num3) && baocard) || (num2 && num3)) {
                    var newCards = clone(cards);
                    var newbaocard = baocard;
                    newCards[i] = num - 1;
                    if (num2) {
                        newCards[i + 1] = num2 - 1;
                    } else {
                        newbaocard--;
                    }
                    if (num3) {
                        newCards[i + 2] = num3 - 1;
                    }
                    else {
                        newbaocard--;
                    }
                    this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                }
                if (num  && baocard >= 2) {
                    cards[i] -= 1;
                    baocard -= 2;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
            }
            break;
        }
    },
    checkBaoPairHuColorCards: function (cards, baocard) {
        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var numOther = 0;
        var colorCardsNum = MJ.sumCardsNum(cards);
        if (colorCardsNum < 1) {
            return true;
        }
        var newcard = baocard;
        ExObject.each(cards, function (c, n) {
            if (n == 1) {
                if (newcard) {
                    newcard--;
                    num2++;
                } else {
                    numOther++;
                }
            } else if (n == 2) {
                if (newcard) {
                    newcard--;
                    num3++;
                } else {
                    num2++;
                }
            } else if (n == 3) {
                num3++;
            } else {
                numOther++;
            }
        });
        if ((numOther == 0) && (num2 <= 1)) {
            return true;
        }
        return false;
    },
    checkHuSettlement: function () {
        return true;
    },
    settlementPatternScore: function () {
        var player = this;
        var room = this.getRoom();

        if (player.existRoundScoreRule(Const.ScoreRule.QG)) {
            var qgs = room.getOption("QGS") || room.getHideOption("QGS");
            var qgScores = {};
            if (qgs == 1) {
                room.enumPlayers(function (eIndex, ePlayer) {
                    if (eIndex != player.getIndex() && ePlayer.isRoundHu()) {
                        ExObject.addNumber(qgScores, eIndex, 9);
                    }
                });
            } else if (qgs == 2) { // 抢杠包N家
                room.enumPlayers(function (eIndex, ePlayer) {
                    if (eIndex != player.getIndex() && ePlayer.isRoundTing()) {
                        ExObject.addNumber(qgScores, eIndex, Const.PatternScore[ePlayer.getRoundPattern()] || 0);
                        if (ePlayer.isRoundHu()) {
                            ExObject.addNumber(qgScores, eIndex, 9);
                        }
                    }
                });
            }

            var totalQGScore = 0;
            ExObject.eachKeyNum(qgScores, function (eIndex, score) {
                var targetPlayer = room.getPlayerByIndex(eIndex);
                if (targetPlayer) {
                    targetPlayer.addRoundScore(score);
                    targetPlayer.addRoundScoreDetail(Const.ScoreReason.QG, score);
                    totalQGScore += score;
                }
            });

            if (totalQGScore) {
                player.addRoundScore(-totalQGScore);
                player.addRoundScoreDetail(Const.ScoreReason.QG, -totalQGScore);
            }
        }

        if (!this.isRoundHu()) {
            return;
        }

        var isLZ = room.getOption('LZ');
        var lzScore = room.getDealerLZ();
        var lzScores = {};
        //if (isLZ && player.getIndex() == room.getDealerIndex() && room.getDealerLZ() > 0) {
        //    this.addRoundItemScores(Const.ScoreRule.LZ, lzScore);
        //}

        var isYQ = room.getOption("YQ");
        if (isYQ && (player.getInitColors().length < room.getSubConfig().colors.length)) {
            this.addRoundItemScores(Const.ScoreRule.YQ, 3);
        }

        // 结算牌型及基础分
        var basicScore = this._stat.roundPatternScore + ExObject.sumValue(this._stat.roundItemScores);

        this._stat.roundTarget.forEach(function (playerIndex) {
            var target = room.getPlayerByIndex(playerIndex);
            if (target) {
                target.addRoundScore(-basicScore);
                target.addRoundScoreDetail(player.getRoundResult(), -basicScore);
                player.addRoundScore(basicScore);

                if (target.isBaoTing()) {
                    var tingScore = Const.ItemScore[Const.ScoreRule.BT];
                    target.addRoundScore(-tingScore);
                    target.addRoundScoreDetail(Const.ScoreReason.BT, -tingScore);
                    player.addRoundScore(tingScore);
                    player.addRoundScoreDetail(Const.ScoreReason.BT, tingScore);
                }

                if (isLZ && room.getDealerLZ() > 0) {
                    if (player.getIndex() == room.getDealerIndex()) {
                        ExObject.addNumber(lzScores, player.getIndex(), lzScore);
                        ExObject.addNumber(lzScores, playerIndex, -lzScore);
                    }

                    if (target.getIndex() == room.getDealerIndex()) {
                        ExObject.addNumber(lzScores, player.getIndex(), lzScore);
                        ExObject.addNumber(lzScores, playerIndex, -lzScore);
                    }
                }
            }
        });

        ExObject.eachKeyNum(lzScores, function (eIndex, eScore) {
            var ePlayer = room.getPlayerByIndex(eIndex);
            if (ePlayer) {
                ePlayer.addRoundScore(eScore);
                ePlayer.addRoundScoreDetail(Const.ScoreReason.LZ, eScore);
            }
        });
    },
    settlement: function () {
         this.addRoundScore(this._score);
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getInfo: function () {
        var info = this._super();
        info.remainScore = this._stat.remainScore;
        return info;
    },

    getReconnectInfo: function (isSelf) {
        var info = this._super(isSelf);
        info.remainScore = this._stat.remainScore;
        info.relpNums = this._lpCards;
        return info;
    },

    getSettlementInfo: function () {
        var info = this._super();
        //this.addRoundScore(this._score);
        this._stat.anGangCount += this._angangCount;        // 暗杠次数
        this._stat.mingGangCount += this._mingGangCount;      // 明杠次数
        this._stat.pengCount += this._pengCount;         //碰的次数
        this._stat.chiCount += this._chiCount;          //吃牌次数

        // //剔除手牌中的胡牌
        // if (this._stat.huCard != 0) {
        //     var handCards = this._handCards.getCards();

        //     handCards[this._stat.huCard] -= 1;
        //     info.handCards = handCards;
        // } else {
        //     info.handCards = this._handCards.getCards();
        // }

        //this.addRoundScore(this._score);
        info._HuStyle = this._HuStyle;
        info._anGangCount = this._angangCount;
        info._mingGangCount = this._mingGangCount;
        info._chiCount = this._chiCount;
        info.gangCards = this._gangCards;
        info.pengCards = this._pengCards;
        info.chiCard = this._chiCards;
        info.handCards = this._handCards.getCards();
        info.playCards = this.getPlayCards();
        info.FS = this._FS;
        info._score = this._score;
        info._lpCards = this._lpCards;
        info._MQ = this._MQ;
        info._baseScore = this._baseScore;
        info._isdp = this._isdp;
        info._isZM = this._isZM;
        return info;
    },

    onStartNewRound: function () {
        this.reset();
        this._super();
        //this._stat.roundRules = {};
    },

    // getInitHandCardPreCards: function () {
    //     var preCards = [];
    //     var distance = this.getRoom().getIndexDistance(this.getIndex(), this.getRoom().getDealerIndex());
    //     if (distance == 0) {

    //         // preCards.push(MJ.getValue(MJ.Color.TIAO, 2));
    //         // preCards.push(MJ.getValue(MJ.Color.TIAO, 3));

    //         // preCards.push(MJ.getValue(MJ.Color.TONG, 9));

    //         //preCards.push(MJ.getValue(MJ.Color.TONG, 4));
    //          preCards.push(MJ.getValue(MJ.Color.ZI, 5));
    //         // preCards.push(MJ.getValue(MJ.Color.TIAO, 2));
    //          preCards.push(MJ.getValue(MJ.Color.ZI, 6));
    //          preCards.push(MJ.getValue(MJ.Color.ZI, 7));
    //         // preCards.push(MJ.getValue(MJ.Color.WAN, 1));

    //         // preCards.push(MJ.getValue(MJ.Color.ZI, 5));
    //         // preCards.push(MJ.getValue(MJ.Color.ZI, 6));
    //         // preCards.push(MJ.getValue(MJ.Color.ZI, 7));

    //     } else if (distance == 1) {


    //         //  preCards.push(MJ.getValue(MJ.Color.ZI, 5));
    //         //  preCards.push(MJ.getValue(MJ.Color.ZI, 6));

    //         //  preCards.push(MJ.getValue(MJ.Color.ZI, 7));
    //         // preCards.push(MJ.getValue(MJ.Color.ZI, 6));

    //         // preCards.push(MJ.getValue(MJ.Color.ZI, 7))
    //     }
    //     //else if(distance == 2){
    //     //     preCards.push(MJ.getValue(MJ.Color.TONG, 6));
    //     //     preCards.push(MJ.getValue(MJ.Color.TONG, 6));
    //     //     preCards.push(MJ.getValue(MJ.Color.TONG, 6));
    //     //
    //     //     preCards.push(MJ.getValue(MJ.Color.TIAO, 7));
    //     //     preCards.push(MJ.getValue(MJ.Color.TIAO, 8));
    //     //
    //     //     preCards.push(MJ.getValue(MJ.Color.TIAO, 9));
    //     //
    //     //     preCards.push(MJ.getValue(MJ.Color.TONG, 7));
    //     //
    //     // }else if(distance == 3){
    //     //     preCards.push(MJ.getValue(MJ.Color.ZI, 5));
    //     //
    //     //     preCards.push(MJ.getValue(MJ.Color.TIAO, 9));
    //     //     preCards.push(MJ.getValue(MJ.Color.TIAO, 9));
    //     //
    //     //     preCards.push(MJ.getValue(MJ.Color.TONG, 7));
    //     //     preCards.push(MJ.getValue(MJ.Color.TONG, 7));
    //     // }

    //     return preCards;
    // },

    liangCard: function () {
        this._handCards.delCard(MJ.ZI.FC);
        this._handCards.delCard(MJ.ZI.HZ);
        this._handCards.delCard(MJ.ZI.BB);
        this._lpCards += 1;
    }
});